<?php

namespace App\Kuafu\Shop\Controller\Internal;

use App\Exceptions\BaseException;
use App\Exceptions\CustomValidateException;
use App\Kuafu\Base\Controller\BaseController;
use App\Kuafu\Base\Enum\BaseCodeEnum;
use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Common\Enum\CodeEnum;
use App\Kuafu\Shop\Enum\ShopCodeEnum;
use App\Kuafu\Shop\Exceptions\ShopException;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Model\ShopBusinessModel;
use App\Kuafu\Shop\Service\OpenShopService;
use App\Kuafu\Shop\Service\ShopAttributeService;
use App\Kuafu\Shop\Service\ShopService;
use App\Kuafu\Shop\Validate\ShopNewValidate;
use App\Kuafu\Shop\Validate\ShopValidate;
use App\Kuafu\User\Enum\RoleCodeEnum;
use App\Kuafu\User\Exceptions\UserException;
use App\Kuafu\WaiMai\Model\WaiMaiShopMappingModel;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\SimpleCache\InvalidArgumentException;

class ShopController extends BaseController
{
    public function shopListByUserId(Request $request)
    {
        $user_id = $request->get('user_id', 0);
        return $this->success(ShopService::getShopListByUserId($user_id, CodeEnum::PLATFORM_BUSINESS));
    }


    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function getFormalUseShopLists(Request $request): JsonResponse
    {
        list($errMsg, $requestParams) = ShopValidate::getFormalUseShopValidate($request->all());
        if ($errMsg) {
            return $this->fail(BaseCodeEnum::ERR_400000, $errMsg);
        }
        return $this->success(ShopService::getUsefulShopLists(strtotime($requestParams['date'])));
    }

    /**
     * 内网创建店铺
     * @param Request $request
     * @return JsonResponse
     * @throws ShopException
     * @throws UserException
     */
    public function create(Request $request)
    {
        $shopCode   = $request->get('shopCode');
        $shopName   = $request->get('shopName');
        $shopMobile = $request->get('shopMobile');
        $contact    = $request->get('contact'); // 联系人
        $type       = $request->get('type'); // 1加盟 2直营
        $address    = $request->get('address'); // 详细地址
        $status     = $request->get('status', \App\Kuafu\Shop\Enum\CodeEnum::SHOP_STATUS_PREPARE); // 2筹备中门店

        $valid = ShopValidate::createShop($request);
        if ($valid) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_INSERT, $valid);
        }

        list($shopId, $shopCode, $password) = ShopService::createShopInternal($request);

        return $this->success(['shopId' => $shopId, 'shopCode' => $shopCode, 'password' => $password]);
    }

    /**
     * 内网更新店铺名称
     * @param Request $request
     * @return JsonResponse
     * @throws ShopException
     * @throws UserException
     */
    public function updateShopName(Request $request)
    {
        $shopCode = $request->get('shopCode');
        $shopName = $request->get('shopName');

        ShopService::updateShopInfo(['shopCode' => $shopCode], ['name' => $shopName]);

        return $this->success();
    }


    /**
     * 内网更新店铺信息
     * @param Request $request
     * @return JsonResponse
     * @throws ShopException
     * @throws UserException
     */
    public function updateShopField(Request $request)
    {
        $conditions = $request->get('conditions');
        $shopField  = $request->get('shopField');

        ShopService::updateShopInfo($conditions, $shopField, 2);

        return $this->success();
    }


    /**
     * 根据code获取店铺信息
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopByCode(Request $request)
    {
        $shopCode = $request->get('shopCode');
        $brandId  = $request->get('brandId');

        $shop = Shop::getShopByCode($shopCode, $brandId);
        if (!$shop) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_ID_NO_EXIST);
        }

        return $this->success($shop->toArray());
    }


    /**
     * 根据code获取店铺信息
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopByCodes(Request $request)
    {
        $shopCodes = $request->get('shopCodes');
        $brandId   = $request->get('brandId');
        $field     = $request->get('fields');

        $shopCodeArr = explode(',', $shopCodes);
        $fieldArr    = $field ? explode(',', $field) : [];

        $shop = Shop::getShopByCodes($shopCodeArr, $brandId, $fieldArr);
        if (!$shop) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_ID_NO_EXIST);
        }

        return $this->success(
            ['shopList' => $shop->toArray()]
        );
    }

    /**
     * 根据shopId获取店铺信息
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopInfo(Request $request)
    {
        if (empty($request->shopId)) {
            $this->fail(ShopCodeEnum::ERR_400000);
        }
        $info = ShopService::getShopInfoShow($request->shopId);
        return $this->success($info);
    }

    /**
     * 根据shopId批量查询店铺信息
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopInfos(Request $request)
    {
        $shopIds = $request->get('shopIds');
        $brandId = $request->get('brandId');
        $field   = $request->get('fields');

        $shopIdsArr = explode(',', $shopIds);
        $fieldArr   = $field ? explode(',', $field) : [];

        $shop = Shop::getShopByIds($shopIdsArr, $brandId, $fieldArr);
        if (!$shop) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_ID_NO_EXIST);
        }

        return $this->success(
            ['shopList' => $shop->toArray()]
        );
    }

    /**
     * 根据shopId获取开业报告信息
     * @param Request $request
     * @return JsonResponse shopCode 门店号  userId 用户 id formalUserAt 正式使用时间
     */
    public function getOpenShopInfo(Request $request)
    {
        $shopCode    = $request->get('shopCode');
        $mobile      = $request->get('mobile');
        $formalUseAt = $request->get('formalUseAt', 0);

        $info = OpenShopService::getOpenShopInfo($shopCode, $mobile, $formalUseAt);
        return $this->success($info);
    }

    /**
     * 根据shopId获取开业N天数据
     * @param Request $request
     * @return JsonResponse
     */
    public function getStartBusinessData(Request $request)
    {
        $shopId    = $request->get('shopId');
        $startDate = $request->get('startDate');
        $day       = $request->get('day');

        $lists = OpenShopService:: getDataStatic($shopId, strtotime($startDate), $day);

        return $this->success(['lists' => $lists]);
    }

    /**
     * 校验开店手动填的shopCode是否能用
     * @param Request $request
     * @return JsonResponse
     * @throws ShopException
     */
    public function checkOpenShopCode(Request $request)
    {
        $shopCode = (int)$request->get('shopCode');
        if (!$shopCode) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_CODE_EMPTY);
        }

        ShopService::chooseShopCode($shopCode);

        return $this->success();
    }

    /**
     * 门店按照省的统计概览
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function overviewByProvinceCodes(Request $request)
    {
        $provinceCodes = $request->get('provinceCodes');
        $openStartTime = $request->get('openStartTime');
        $openEndTime   = $request->get('openEndTime');

        $this->validate($request, [
            'provinceCodes' => 'required|array',
            'openStartTime' => 'required|integer',
            'openEndTime'   => 'required|integer',
        ]);

        $lists = ShopService::overviewByProvinceCodes($provinceCodes, $openStartTime, $openEndTime);

        return $this->success(['lists' => $lists]);
    }

    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopFunctionOpenDetail(Request $request): JsonResponse
    {
        if (empty($request->shopId)) {
            $this->fail(ShopCodeEnum::ERR_400000);
        }
        return $this->success(ShopService::getShopFunctionOpenDetail($request->shopId));
    }


    /**
     * 选址报告完成同步门店信息
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws NotFoundExceptionInterface
     * @throws GuzzleException
     * @throws InvalidArgumentException
     */
    public function synchronizeShopInfo(Request $request): JsonResponse
    {
        $params = ShopNewValidate::synchronizeShopInfoValidate($request->all());
        ShopService::synchronizeShopInfo($params);
        return $this->success();
    }

    /**
     * 启用门店
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws NotFoundExceptionInterface
     * @throws CustomValidateException
     * @throws ContainerExceptionInterface
     */
    public function switchShopOn(Request $request): JsonResponse
    {
        $params = ShopNewValidate::switchShopOnValidate($request->all());
        ShopService::switchShopOn($params);
        return $this->success();
    }

    /**
     * 闭店
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws GuzzleException
     * @throws InvalidArgumentException
     * @throws NotFoundExceptionInterface
     */
    public function closeShop(Request $request): JsonResponse
    {
        $params = ShopNewValidate::closeShopValidate($request->all());
        ShopService::closeShop($params);
        return $this->success();
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws GuzzleException
     * @throws InvalidArgumentException
     * @throws NotFoundExceptionInterface
     */
    public function updateShopMobile(Request $request): JsonResponse
    {
        $params = ShopNewValidate::updateShopMobileValidate($request->all());
        ShopService::updateShopMobile($params);
        return $this->success();
    }

    /**
     * 城市门店列表
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws InvalidArgumentException
     * @throws NotFoundExceptionInterface
     */
    public function cityShop(Request $request): JsonResponse
    {
        $params = ShopNewValidate::cityShopValidate($request->all());
        return $this->success(ShopService::cityShop($params));
    }

    /**
     * 通过门店名称，查询门店信息
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopByName(Request $request): JsonResponse
    {
        $name   = (string)$request->get('name');
        $fields = (array)$request->get('fields', ['*']);

        $this->validate($request, [
            'name'  => 'required|string|min:3',
            'field' => 'array',
        ]);

        $data = Shop::query()->where('name', 'like', "%{$name}%")->select($fields)->get()->toArray();

        return $this->success($data);
    }

    /**
     * 稽核门店范围筛选
     * @param Request $request
     * @return JsonResponse
     */
    public function cruiseShopFilter(Request $request): JsonResponse
    {
        $pageSize        = (int)$request->get('pageSize');
        $pageNum         = (int)$request->get('pageNum');
        $provinceCode    = $request->get('provinceCode');
        $cityCode        = $request->get('cityCode');
        $regionCode      = $request->get('regionCode');
        $status          = $request->get('status');
        $level           = (int)$request->get('level');
        $orderRatioStart = (float)$request->get('orderRatioStart');
        $orderRatioEnd   = (float)$request->get('orderRatioEnd');
        $lastCruiseTime  = (int)$request->get('lastCruiseTime');
        $shopIds         = $request->get('shopIds') ? (array)$request->get('shopIds') : [];

        $paginator = ShopBusinessModel::query()
                                      ->join('shops', 'shops.id', '=', 'shop_business.shopId')
                                      ->where('isNew', ShopBusinessModel::IS_NEW_ON)
                                      ->when($shopIds, function ($query) use ($shopIds) {
                                          $query->whereIn('shops.id', $shopIds);
                                      })
                                      ->when($provinceCode, function ($query) use ($provinceCode) {
                                          $query->where('shops.province', $provinceCode);
                                      })
                                      ->when($cityCode, function ($query) use ($cityCode) {
                                          $query->where('shops.city', $cityCode);
                                      })
                                      ->when($regionCode, function ($query) use ($regionCode) {
                                          $query->where('shops.district', $regionCode);
                                      })
                                      ->when($status !== null, function ($query) use ($status) {
                                          $query->where('shops.status', $status);
                                      })
                                      ->when($level, function ($query) use ($level) {
                                          switch ($level) {
                                              case 1:
                                                  $shopGrade = ['问题', 'ST'];
                                                  break;
                                              case 2:
                                                  $shopGrade = '瘦狗';
                                                  break;
                                              case 3:
                                                  $shopGrade = '金牛';
                                                  break;
                                              case 4:
                                                  $shopGrade = '明星';
                                                  break;
                                              default:
                                                  return;
                                          }

                                          if (is_array($shopGrade)) {
                                              $query->whereIn('shop_business.shopGrade', $shopGrade);
                                          } else {
                                              $query->where('shop_business.shopGrade', $shopGrade);
                                          }
                                      })
                                      ->when($orderRatioStart, function ($query) use ($orderRatioStart) {
                                          $query->where('shop_business.orderRatio', '>=', $orderRatioStart);
                                      })
                                      ->when($orderRatioEnd, function ($query) use ($orderRatioEnd) {
                                          $query->where('shop_business.orderRatio', '<=', $orderRatioEnd);
                                      })
                                      ->when($lastCruiseTime, function ($query) use ($lastCruiseTime) {
                                          $query->where('shop_business.lastCruiseTime', '<=', $lastCruiseTime);
                                      })
                                      ->select(['shops.*', 'shop_business.shopGrade', 'shop_business.orderRatio', 'shop_business.lastCruiseTime'])
                                      ->paginate($pageSize, ['*'], 'pageNum', $pageNum);

        $data = BaseService::pageLists($paginator, function ($item) {
            switch ($item['shopGrade']) {
                case '问题':
                case 'ST':
                    $grade = 1;
                    break;
                case '瘦狗':
                    $grade = 2;
                    break;
                case '金牛':
                    $grade = 3;
                    break;
                case '明星':
                    $grade = 4;
                    break;
                default:
                    $grade = 0;
            }
            $item['grade'] = $grade;

            return $item;
        });

        return $this->success($data);
    }

    public function shopBusiness(Request $request): JsonResponse
    {
        $shopIds = $request->get('shopIds');
        $fields  = $request->get('fields', ['*']);

        $this->validate($request, [
            'shopIds' => 'required|array',
            'fields'  => 'array',
        ]);

        $data = ShopBusinessModel::query()
                                 ->whereIn('shopId', $shopIds)
                                 ->where('isNew', ShopBusinessModel::IS_NEW_ON)
                                 ->select($fields)
                                 ->get()
                                 ->toArray();

        return $this->success($data);
    }

    /**
     * 模糊查询门店信息
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws InvalidArgumentException
     * @throws NotFoundExceptionInterface
     */
    public function getShopInfoByLikeSearch(Request $request): JsonResponse
    {
        $params = ShopNewValidate::likeSearchValidate($request->all());
        return $this->success(ShopService::getShopInfoByLikeSearch($params));
    }


    /**
     * 模糊查询门店信息
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws InvalidArgumentException
     * @throws NotFoundExceptionInterface
     */
    public function getShopList(Request $request): JsonResponse
    {
        $params = ShopNewValidate::likeSearchParamsValidate($request->all());
        return $this->success(ShopService::getShopListWithParams($params));
    }

    public function getShopStaffListByShopId(Request $request)
    {
        $shopId        = $request->get('shopId', 0);
        $filterWebUser = $request->get('filterWebUser', true);
        $type          = $request->get('type', '');// 角色平台类型

        if (!$type) {
            $type = [RoleCodeEnum::ROLE_BUSINESS_TYPE, RoleCodeEnum::ROLE_POS_TYPE];
        } else {
            $type = explode(',', $type);
        }

        return $this->success(ShopService::getShopStaffInfo($shopId, \App\Kuafu\User\Enum\CodeEnum::USER_STATUS_USE,
            $filterWebUser, $type));
    }

    /**
     * 解绑功能开通
     * @param Request $request
     */
    public function unbindFunctionOpen(Request $request)
    {
        $shopId     = $request->post('shopId');
        $sourceType = $request->post('sourceType');

        $this->validate($request, [
            'shopId'     => 'required|integer|min:1',
            'sourceType' => 'required|integer',
        ]);

        $rows = WaiMaiShopMappingModel::delData($shopId, $sourceType);

        return $this->success(['rows' => $rows]);
    }


    /**
     * 根据门店id获取门店详细信息
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws InvalidArgumentException
     * @throws NotFoundExceptionInterface
     */
    public function getShopDetailByShopId(Request $request): JsonResponse
    {
        $params = ShopNewValidate::getShopDetailByShopIdValidate($request->all());
        return $this->success(ShopService::getShopDetailByShopId($params));
    }


    /**
     * 门店富有支付配置新增
     *
     * @param Request $request
     * @param $shopId
     * @param $paymentId
     * @return JsonResponse
     * @throws ShopException
     */
    public function shopFuYouPaymentsEdit(Request $request, $shopId, $paymentId): JsonResponse
    {
        list($errMsg, $requestParams) = ShopValidate::shopPaymentsEditValidate(
            $request->merge(['paymentId' => $paymentId, 'shopId' => $shopId])->all()
        );
        if ($errMsg) {
            return $this->fail(BaseCodeEnum::ERR_400000, $errMsg);
        }
        $uid = $request->get('uid', 0);

        ShopService::shopPaymentsEdit($requestParams, $uid, $shopId);
        return $this->success([]);
    }


    /**
     * 查询门店属性
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopAttribute(Request $request): JsonResponse
    {
        $shopIds = (array)$request->get('shopIds', []);
        if (!$shopIds) {
            return $this->success([]);
        }
        return $this->success(ShopAttributeService::getShopAttribute($shopIds));
    }


    /**
     * 编辑门店属性
     * @param Request $request
     * @param int $shopId
     * @return JsonResponse
     */
    public function updateShopAttribute(Request $request, int $shopId): JsonResponse
    {
        $data['shopType']                  = (string)$request->get('shopType', '');// 店型
        $data['siteSelection']             = (string)$request->get('siteSelection', '');// 选址场景
        $data['siteSelectionGrade']        = (string)$request->get('siteSelectionGrade', '');// 场景等级
        $data['posLine']                   = (string)$request->get('posLine', '');// 点餐动线
        $data['engineeringExhibitionArea'] = (string)$request->get('engineeringExhibitionArea', '');// 工程条件-展面
        $data['engineeringArea']           = (string)$request->get('engineeringArea', '');// 工程条件-面积
        $data['engineeringElectricity']    = (string)$request->get('engineeringElectricity', '');// 工程条件-电量
        $data['engineeringDepth']          = (string)$request->get('engineeringDepth', '');// 工程条件-进深
        $data['menuLevel']                 = (string)$request->get('menuLevel', '');// 菜单等级
        $data['sellingCategory']           = (string)$request->get('sellingCategory', '');// 售卖品类
        $data['relocationStatus']          = (string)$request->get('relocationStatus', '');// 迁址状态
        $data['posType']                   = (string)$request->get('posType', '');// 收银设备
        $data['shopStatusText']            = (string)$request->get('shopStatusText', '');// 门店阶段-筹备中
        $rmsUserId                         = (int)$request->get('rmsUserId', 0);
        if ($data['posType']) {
            $data['posType'] = ShopAttributeService::getPosType($data['posType']);
        }
        if ($data['shopStatusText']) {
            $data['status'] = ShopAttributeService::getShopStatusByText($data['shopStatusText']);
        }
        return $this->success(ShopAttributeService::updateShopAttribute($shopId, $rmsUserId, $data));
    }


    /**
     * 查询门店属性配置项
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopAttributeData(Request $request): JsonResponse
    {
        return $this->success(ShopAttributeService::getAttributeList());
    }
}
